﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Text;

namespace Dapper_Core.DAL.Interface
{
    public interface IBaseRepository<T>
    {
        #region 增
        /// <summary>
        /// 插入实体对象
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool Add(T model, int? commandTimeout = null);

        /// <summary>
        /// 插入实体对象列表
        /// </summary>
        /// <param name="modelList">实体对象列表</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool AddList(IEnumerable<T> modelList, int? commandTimeout = null);
        #endregion

        #region 删
        /// <summary>
        /// 删除实体对象
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool Delete(object id, int? commandTimeout = null);

        /// <summary>
        /// 删除实体对象
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool Delete(T model, int? commandTimeout = null);

        /// <summary>
        /// 删除实体对象列表
        /// </summary>
        /// <param name="modelList">实体对象列表</param>
        /// <param name="searchNull">=、大于等于、小于等于、!=是否处理null参数值（true时：Name = null 转换成Name is null，false时：Name = null直接忽略不生成查询条件）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool DeleteList(IEnumerable<T> modelList, int? commandTimeout = null);

        /// <summary>
        /// 根据条件进行删除
        /// </summary>
        /// <param name="exp">Expression表达式</param>
        /// <param name="searchNull">=、大于等于、小于等于、!=是否处理null参数值（true时：Name = null 转换成Name is null，false时：Name = null直接忽略不生成查询条件）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        bool DeleteList(Expression<Func<T, bool>> exp, bool searchNull = false, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件进行删除
        /// </summary>
        /// <param name="where">查询条件（包含where关键字）</param>
        /// <param name="parameters">参数对象（默认是null）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        bool DeleteList(string where, object parameters = null, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件进行删除
        /// </summary>
        /// <param name="whereConditions">查询条件，示例：new {Category = 1, SubCategory=2}</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        bool DeleteList(object whereConditions, int? commandTimeout = null);

        /// <summary>
        /// 对数据进行软删除
        /// </summary>
        /// <param name="exp">Expression表达式</param>
        /// <param name="deleter">删除者</param>
        /// <param name="deleteDate">删除时间</param>
        /// <param name="searchNull">=、大于等于、小于等于、!=是否处理null参数值（true时：Name = null 转换成Name is null，false时：Name = null直接忽略不生成查询条件）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        bool SoftDelete(Expression<Func<T, bool>> exp, string deleter, DateTime deleteDate, bool searchNull = false, int? commandTimeout = null);
        #endregion

        #region 改
        /// <summary>
        /// 修改实体对象
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool Update(T model, int? commandTimeout = null);

        /// <summary>
        /// 修改实体对象列表
        /// </summary>
        /// <param name="modelList">实体对象列表</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool UpdateList(IEnumerable<T> modelList, int? commandTimeout = null);

        /// <summary>
        /// 修改实体对象（仅修改非空字段）
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool UpdateNotNull(T model, int? commandTimeout = null);

        /// <summary>
        /// 修改实体对象列表（仅修改非空字段）
        /// </summary>
        /// <param name="modelList">实体对象列表</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        bool UpdateNotNullList(IEnumerable<T> modelList, int? commandTimeout = null);
        #endregion

        #region 查
        /// <summary>
        /// 根据Id获取实体对象
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        T Get(object id, int? commandTimeout = null);

        /// <summary>
        /// 根据Expression获取实体列表
        /// </summary>
        /// <param name="exp">Expression表达式</param>
        /// <param name="orderby">排序条件（可指定asc、desc）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        IEnumerable<T> GetList(Expression<Func<T, bool>> exp, bool searchNull = false, string orderby = null, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取实体列表
        /// </summary>
        /// <param name="where">查询条件（包含where关键字）</param>
        /// <param name="parameters">参数对象（默认是null）</param>
        /// <param name="orderby">排序条件（可指定asc、desc）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        IEnumerable<T> GetList(string where, object parameters = null, string orderby = null, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取实体列表
        /// </summary>
        /// <param name="whereConditions">查询条件，示例：new {Category = 1, SubCategory=2}</param>
        /// <param name="orderby">排序条件（可指定asc、desc）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        IEnumerable<T> GetList(object whereConditions, string orderby = null, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取分页实体列表
        /// </summary>
        /// <param name="pageNumber">页索引（从1开始）</param>
        /// <param name="rowsPerPage">每页有几条数据</param>
        /// <param name="exp">查询条件表达式</param>
        /// <param name="orderby">排序字段（可指定asc、desc）</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        IEnumerable<T> GetPagelist(int pageNumber, int rowsPerPage, Expression<Func<T, bool>> exp, string orderby, bool searchNull = false, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取分页实体列表
        /// </summary>
        /// <param name="pageNumber">页索引（从1开始）</param>
        /// <param name="rowsPerPage">每页有几条数据</param>
        /// <param name="where">查询条件</param>
        /// <param name="orderby">排序字段（可指定asc、desc）</param>
        /// <param name="parameters">参数对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        IEnumerable<T> GetPagelist(int pageNumber, int rowsPerPage, string where, string orderby, object parameters = null, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取信息数量
        /// </summary>
        /// <param name="exp">Expression表达式</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        int GetListCount(Expression<Func<T, bool>> exp, bool searchNull = false, int? commandTimeout = null);

        /// <summary>
        /// 根据查询条件获取信息数量
        /// </summary>
        /// <param name="where">查询条件</param>
        /// <param name="parameters">参数对象</param>
        /// <param name="commandTimeout">数据库超时时间（默认是null）</param>
        /// <returns></returns>
        int GetListCount(string where, object parameters = null, int? commandTimeout = null);
        #endregion

        #region 执行SqlMap.xml中的Sql语句
        /// <summary>
        /// 根据id执行SqlMap.xml中对应的Sql语句
        /// </summary>
        /// <param name="sqlId"></param>
        /// <param name="webParas"></param>
        /// <returns></returns>
        IEnumerable<T> QueryMap(string sqlId, Dictionary<string, string> webParas);

        /// <summary>
        /// 根据id执行SqlMap.xml中对应的Sql语句
        /// </summary>
        /// <param name="sqlId"></param>
        /// <param name="webParas"></param>
        /// <returns></returns>
        T QueryMapModel(string sqlId, Dictionary<string, string> webParas);

        /// <summary>
        /// 根据id执行SqlMap.xml中对应的Sql语句
        /// </summary>
        /// <typeparam name="T2"></typeparam>
        /// <param name="sqlId"></param>
        /// <param name="webParas"></param>
        /// <returns></returns>
        IEnumerable<T2> QueryMap<T2>(string sqlId, Dictionary<string, string> webParas);

        /// <summary>
        /// 根据id执行SqlMap.xml中对应的Sql语句
        /// </summary>
        /// <typeparam name="T2"></typeparam>
        /// <param name="sqlId"></param>
        /// <param name="webParas"></param>
        /// <returns></returns>
        T2 QueryMapModel<T2>(string sqlId, Dictionary<string, string> webParas);
        #endregion

        #region 执行存储过程
        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procName">存储过程的名称</param>
        /// <param name="parameters">所需参数</param>
        /// <returns></returns>
        bool ExecuteProc(string procName, object parameters);

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procName">存储过程的名称</param>
        /// <param name="parameters">所需参数</param>
        /// <returns></returns>
        object ExecuteProcScalar(string procName, object parameters);

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procName">存储过程的名称</param>
        /// <param name="parameters">所需参数</param>
        /// <returns></returns>
        IEnumerable<T> ExecuteProcQuery(string procName, object parameters);

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="procName">存储过程的名称</param>
        /// <param name="parameters">所需参数</param>
        /// <returns></returns>
        T ExecuteProcModel(string procName, object parameters);
        #endregion

        #region 作为扩展方法转移到BaseRepositoryExt
        /// <summary>
        /// 执行Sql语句返回泛型集合，返回值类型可以与IBaseRepository<T>指定的T不同
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        //IEnumerable<T2> Query<T2>(string sql, object parameters);

        /// <summary>
        /// 执行Sql语句返回泛型对象，返回值类型可以与IBaseRepository<T>指定的T不同
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        //T2 QueryModel<T2>(string sql, object parameters); 
        #endregion
    }
}
